/**
 * 
 */
package sudoku.util.game;

import java.awt.Dialog;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Calendar;

import javax.swing.JOptionPane;

import sudoku.model.SudokuModel;
import sudoku.ui.GameChoiceUI;
import sudoku.ui.SudokuUI;
import sudoku.util.Config;
import sudoku.util.Data;
import sudoku.util.Language;

/**
 * @author Romet
 * 
 */
public class Database implements Runnable {

  private volatile Config config;
  private volatile SudokuUI m2ng;
  private volatile SudokuModel model;

  private volatile Data data;
  private volatile GameChoiceUI gameChoiceUI;
  private volatile Language language;

  private String mode;
  private Dialog d;

  public Database(String mode, Dialog d) {
    this.mode = mode;
    this.d = d;
  }

  @Override
  public void run() {
    if (mode.equals("add")) {
      salvestaAndmebaasi();
      d.dispose();
    }
    if (mode.equals("set")) {
      seaAndmebaas();
      d.dispose();
      gameChoiceUI.setvalik();
    }
    m2ng.setEnabled(true);
    m2ng.requestFocus();
  }

  public void salvestaAndmebaasi() {
    try {
      boolean k2ib = m2ng.m2nguTimer.isRunning();
      if (k2ib) {
        m2ng.m2nguTimer.stop();
      }
      String s = model.getLahendus(false);
      SolveDLX sdlx = new SolveDLX(config.getRuudustik());
      sdlx.BuildSudokuMatrix();
      sdlx.SetStartingGrid(s);
      sdlx.SolveSudoku(SolveDLX.STOP_AT_SECOND);
      if (sdlx.unique) {
        if (model.getLevel().equals(language.getSudoku_diffextreme())) {
          JOptionPane.showMessageDialog(m2ng, language.getDLX_difficultyerror(), language.getMessage(), JOptionPane.INFORMATION_MESSAGE);
          return;
        }
        URLConnection cohttp = (new URL("http://web.zone.ee/Arch_Devil002/sudokus.txt").openConnection());
        cohttp.setRequestProperty("Cookie", "MSNSplash2=OK");
        BufferedReader re = new BufferedReader(new InputStreamReader(cohttp.getInputStream()));
        StringBuffer eel = new StringBuffer();
        String ss = "";
        int nr = 0;
        while ((ss = re.readLine()) != null) {
          if (model.getLahendus(false).equals(ss)) {
            JOptionPane.showMessageDialog(m2ng, language.getDLX_doubleerror(), language.getMessage(), JOptionPane.INFORMATION_MESSAGE);
            return;
          }
          eel.append(ss + "\n");
          nr++;
        }
        re.close();
        URLConnection con = (new URL("ftp://Arch_Devil002:58RjZz@web.zone.ee/sudokus.txt").openConnection());
        con.setDoOutput(true);
        con.setDoInput(true);
        BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(con.getOutputStream()));
        eel.append(s);
        wr.write(eel.toString());
        wr.flush();
        wr.close();
        URLConnection co = (new URL("http://web.zone.ee/Arch_Devil002/sudokus.ver").openConnection());
        co.setRequestProperty("Cookie", "MSNSplash2=OK");
        re = new BufferedReader(new InputStreamReader(co.getInputStream()));
        String ver = re.readLine();
        re.close();
        String uusver = String.valueOf(Integer.parseInt(ver) + 1);
        config.setDatabaseVersion(uusver);
        con = (new URL("ftp://Arch_Devil002:58RjZz@web.zone.ee/sudokus.ver").openConnection());
        wr = new BufferedWriter(new OutputStreamWriter(con.getOutputStream()));
        wr.write(config.getDatabaseVersion());
        wr.flush();
        wr.close();
        wr = new BufferedWriter(new FileWriter("sudokus.txt"));
        wr.write(eel.toString());
        wr.flush();
        wr.close();
        URLConnection connhttp = (new URL("http://web.zone.ee/Arch_Devil002/sudoku.history").openConnection());
        URLConnection connftp = (new URL("ftp://Arch_Devil002:58RjZz@web.zone.ee/sudoku.history").openConnection());
        connftp.setDoOutput(true);
        connhttp.setRequestProperty("Cookie", "MSNSplash2=OK");
        re = new BufferedReader(new InputStreamReader(connhttp.getInputStream()));
        StringBuffer sb = new StringBuffer();
        ss = "";
        while ((ss = re.readLine()) != null) {
          sb.append(ss + "\n");
        }
        re.close();
        wr = new BufferedWriter(new OutputStreamWriter(connftp.getOutputStream()));
        Calendar cal = Calendar.getInstance();
        sb.append(cal.get(Calendar.DAY_OF_MONTH) + ".");
        sb.append((cal.get(Calendar.MONTH) + 1) + ".");
        sb.append(cal.get(Calendar.YEAR) + " ");
        sb.append(cal.get(Calendar.HOUR_OF_DAY) + ":");
        sb.append(cal.get(Calendar.MINUTE) + ":");
        sb.append(cal.get(Calendar.SECOND) + ",");
        sb.append(cal.get(Calendar.MILLISECOND) + " --> ");
        sb.append((nr + 1) + ". by ");
        sb.append(config.getNimi());
        wr.write(sb.toString());
        wr.flush();
        wr.close();
        if (k2ib) {
          m2ng.m2nguTimer.start();
        }
      } else {
        JOptionPane.showMessageDialog(m2ng, language.getDLX_adderror(), language.getMessage(), JOptionPane.INFORMATION_MESSAGE);
      }
    } catch (Exception e) {
      /*
       * try { String s = model.getLahendus(false); SolveDLX sdlx=new
       * SolveDLX(config.getRuudustik()); sdlx.BuildSudokuMatrix();
       * sdlx.SetStartingGrid(s);
       * sdlx.SolveSudoku(sudoku.util.game.SolveMethod.StopAtSecond); if
       * (sdlx.unique) { BufferedReader re = new BufferedReader(new
       * FileReader("sudoku.txt")); String eel = ""; String ss = ""; while ((ss
       * = re.readLine()) != null) { eel += ss + "\n"; } re.close();
       * BufferedWriter wr = new BufferedWriter(new FileWriter("sudoku.txt"));
       * wr.write(eel); wr.write(s); wr.flush(); wr.close(); } else {
       * JOptionPane.showMessageDialog(m2ng, language.getDLX_adderror(),
       * language.getMessage(), JOptionPane.INFORMATION_MESSAGE); } } catch
       * (Exception er) {
       * Config.log(er.getClass().toString()+": "+er.getMessage(),
       * er.getStackTrace()); }
       */
      Config.log(e.getClass().toString() + ": " + e.getMessage(), e.getStackTrace());
      JOptionPane.showMessageDialog(m2ng, language.getConnectionError(), language.getMessage(), JOptionPane.INFORMATION_MESSAGE);
    }
  }

  public void seaAndmebaas() {
    try {
      URLConnection co = (new URL("http://web.zone.ee/Arch_Devil002/sudokus.ver").openConnection());
      co.setRequestProperty("Cookie", "MSNSplash2=OK");
      BufferedReader re = new BufferedReader(new InputStreamReader(co.getInputStream()));
      data.setOlemasolevadM2ngud9(new ArrayList<String>());
      data.setOlemasolevadM2ngud16(new ArrayList<String>());
      String ver = re.readLine();
      re.close();
      if (!ver.equals(config.getDatabaseVersion())) {
        URLConnection con = (new URL("http://web.zone.ee/Arch_Devil002/sudokus.txt").openConnection());
        con.setRequestProperty("Cookie", "MSNSplash2=OK");
        re = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String ss = "";
        String eel = "";
        boolean b = false;
        while ((ss = re.readLine()) != null) {
          if (ss.length() < 256) {
            data.getOlemasolevadM2ngud9().add(ss);
          } else {
            data.getOlemasolevadM2ngud16().add(ss);
          }
          if (b) {
            eel += "\n";
          } else {
            b = true;
          }
          eel += ss;
        }
        re.close();
        BufferedWriter wr = new BufferedWriter(new FileWriter("sudokus.txt"));
        wr.write(eel);
        wr.flush();
        wr.close();
        config.setDatabaseVersion(ver);
      } else {
        re = new BufferedReader(new FileReader("sudokus.txt"));
        String ss = "";
        while ((ss = re.readLine()) != null) {
          int ssl = ss.length();
          String uus = "";
          for (int i = 0; i < ss.length(); i++) {
            if (ss.length() == 81) {
              if (ss.charAt(i) == '.' || ss.charAt(i) == '0') {
                uus += " ";
              } else {
                uus += ss.charAt(i);
              }
            } else if ((ss.charAt(i) == '.' || ss.charAt(i) == '0') && (i == 0 || ss.charAt(i - 1) == ',')) {
              uus += " ";
            } else {
              uus += ss.charAt(i);
            }
            if (ssl == 81 && i != 80) {
              uus += ",";
            }
          }
          if (uus.length() < 256) {
            data.getOlemasolevadM2ngud9().add(uus);
          } else {
            data.getOlemasolevadM2ngud16().add(uus);
          }
        }
        re.close();
      }
    } catch (Exception e) {
      try {
        BufferedReader re = new BufferedReader(new FileReader("sudokus.txt"));
        data.setOlemasolevadM2ngud9(new ArrayList<String>());
        data.setOlemasolevadM2ngud16(new ArrayList<String>());
        String ss = "";
        while ((ss = re.readLine()) != null) {
          int ssl = ss.length();
          String uus = "";
          for (int i = 0; i < ss.length(); i++) {
            if ((ss.charAt(i) == '.' || ss.charAt(i) == '0') && (i == 0 || ss.charAt(i - 1) == ',')) {
              uus += " ";
            } else {
              uus += ss.charAt(i);
            }
            if (ssl == 81 && i != 80) {
              uus += ",";
            }
          }
          if (uus.length() < 256) {
            data.getOlemasolevadM2ngud9().add(uus);
          } else {
            data.getOlemasolevadM2ngud16().add(uus);
          }
        }
        re.close();
      } catch (Exception er) {
        Config.log(er.getClass().toString() + ": " + er.getMessage(), er.getStackTrace());
      }
      Config.log(e.getClass().toString() + ": " + e.getMessage(), e.getStackTrace());
      JOptionPane.showMessageDialog(m2ng, language.getError(), language.getMessage(), JOptionPane.INFORMATION_MESSAGE);
    }
  }

  public void setConfig(Config config) {
    this.config = config;
  }

  public void setData(Data data) {
    this.data = data;
  }

  public void setGameChoiceUI(GameChoiceUI gameChoiceUI) {
    this.gameChoiceUI = gameChoiceUI;
  }

  public void setLanguage(Language language) {
    this.language = language;
  }

  public void setM2ng(SudokuUI m2ng) {
    this.m2ng = m2ng;
  }

  public void setModel(SudokuModel model) {
    this.model = model;
  }
}
